package com.ruiyou.ub;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class ScanningActivity extends AppCompatActivity {
    static final String EXTRA_RESULT = "result_message";
    private static final String[] PS = {Manifest.permission.CAMERA};
    private final Executor cameraExecutor = Executors.newSingleThreadExecutor();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.scanning);
        if (allPermissionsGranted()) {
            startCamera();
        } else {
            ActivityCompat.requestPermissions(this, PS, 1);
        }
    }

    private boolean allPermissionsGranted() {
        for (String p : PS) {
            if (ContextCompat.checkSelfPermission(this, p) !=
                    PackageManager.PERMISSION_GRANTED)
                return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode,
            @NonNull String[] permissions,
            @NonNull int[] grantResults
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (allPermissionsGranted()) {
            startCamera();
        } else {
            exitWithResult(RESULT_CANCELED, "Permission denied!");
        }
    }

    private void startCamera() {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
                ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            // preview
            Preview preview = new Preview.Builder().build();
            preview.setSurfaceProvider(
                    ((PreviewView) findViewById(R.id.scanning_preview))
                            .getSurfaceProvider()
            );
            // scan
            ImageAnalysis analysis = new ImageAnalysis.Builder()
                    .build();
            analysis.setAnalyzer(cameraExecutor, image -> {
                String result = Util.decodeQRCode(image);
                image.close();
                if (result != null) {
                    exitWithResult(RESULT_OK, result);
                }
            });
            // start
            try {
                ProcessCameraProvider provider = cameraProviderFuture.get();
                provider.unbindAll();
                provider.bindToLifecycle(
                        this,
                        CameraSelector.DEFAULT_BACK_CAMERA,
                        preview, analysis
                );
            } catch (Exception e) {
                exitWithResult(RESULT_CANCELED, e.getMessage());
            }
        }, ContextCompat.getMainExecutor(this));
    }

    private void exitWithResult(int resultCode, String msg) {
        Intent intent = getIntent();
        if (resultCode == RESULT_OK) {
            intent.putExtra(EXTRA_RESULT, msg);
        } else {
            Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
        }
        setResult(resultCode, intent);
        finish();
    }
}
